﻿using System;
using System.Web.UI.WebControls;
using DBProvider.Providers;
using DBProvider;
using System.IO;
using System.Web;
using System.Text;
using System.Collections.Generic;

namespace HealthCommunity.Controls
{
	public partial class UCMaterialList : System.Web.UI.UserControl
	{
		private IMaterialProvider _MaterialProvider;

		private IList<Material> _DataSource;
		private int _TotalRecords;

		public IList<Material> DataSourse
		{
			get
			{
				var pageIndex = this.PageIndex;
				var totalRecords = 0;
				var pageSize = this.PageSize;

				var selectedItem = ddlMaterialCategory.SelectedValue;

				if(!string.IsNullOrEmpty(selectedItem))
				{
					var selectedMatCatID = int.Parse(selectedItem);

					if(_MaterialProvider == null)
					{
						_MaterialProvider = new MaterialProvider();
					}

					var user = SiteContext.Current.CurrentUser;

					if(user != null)
					{
						if(selectedMatCatID == 0)
						{
							if(user.Role.RoleName.ToLower().Equals("admin"))
							{
								var drugStore = SiteContext.Current.CurrentDrugStore;

								if(drugStore != null)
								{
									_DataSource = _MaterialProvider.GetAllMaterial(pageIndex, pageSize, out totalRecords, drugStore.DrugStoreID);
								}
							}
							else
							{
								if(user.DrugStoreID.GetValueOrDefault(0) > 0)
								{
									_DataSource = _MaterialProvider.GetAllMaterial(user.UserID, pageIndex, pageSize, out totalRecords, user.DrugStoreID.GetValueOrDefault(0));
								}
							}
						}
						else
						{
							if(user.Role.RoleName.ToLower().Equals("admin"))
							{
								var drugStore = SiteContext.Current.CurrentDrugStore;

								if(drugStore != null)
								{
									_DataSource = _MaterialProvider.GetMaterialByCategory(selectedMatCatID, pageIndex, pageSize, out totalRecords, drugStore.DrugStoreID);
								}
							}
							else
							{
								if(user.DrugStoreID.GetValueOrDefault(0) > 0)
								{
									_DataSource = _MaterialProvider.GetMaterialByCategory(user.UserID, selectedMatCatID, pageIndex, pageSize, out totalRecords, user.DrugStoreID.GetValueOrDefault(0));
								}
							}
						}
					}
				}

				this.TotalRecords = totalRecords;

				return _DataSource;
			}
		}

		public int PageIndex
		{
			get
			{
				if(ViewState["PageIndex"] == null)
				{
					return 0;
				}
				else
				{
					return int.Parse(ViewState["PageIndex"].ToString());
				}
			}
			set
			{
				ViewState["PageIndex"] = value;
			}
		}

		public int TotalRecords
		{
			get
			{
				return _TotalRecords;
			}
			set
			{
				_TotalRecords = value;
			}
		}

		public int TotalPages
		{
			get
			{
				var data = _DataSource == null ? this.DataSourse : _DataSource;

				if(data == null)
				{
					return 0;
				}

				int totalRecords = TotalRecords;

				int totalPages = 0;

				if(totalRecords <= PageSize)
				{
					totalPages = 1;
				}

				if(totalRecords % PageSize == 0)
				{
					totalPages = totalRecords / PageSize;
				}

				if(totalRecords % PageSize > 0)
				{
					totalPages = totalRecords / PageSize + 1;
				}

				return totalPages;
			}
		}

		public int PageSize
		{
			get
			{
				return int.Parse(ddlPageSize.SelectedValue);
			}
		}

		protected void Page_Load(object sender, EventArgs e)
		{
			if(!IsPostBack)
			{
				BindMaterialCategory();
			}
		}

		protected void ddlPageSize_SelectedIndexChanged(object sender, EventArgs e)
		{
			this.PageIndex = 0;
		}

		protected void LBPageIndex_Command(object sender, System.Web.UI.WebControls.CommandEventArgs e)
		{
			switch(e.CommandName)
			{
				case "PageIndex":
					{
						LinkButton theLink = sender as LinkButton;

						int index = int.Parse(theLink.Text);

						PageIndex = index - 1;

						//TotalRecords = DataSource.Count();

						BindMaterial();
					}
					break;
			}
		}

		protected void lbtnFirstPage_Click(object sender, EventArgs e)
		{
			PageIndex = 0;
			BindMaterial();
		}

		protected void lbtnLastPage_Click(object sender, EventArgs e)
		{
			PageIndex = TotalPages - 1;
			BindMaterial();
		}

		protected void Page_PreRender(object sender, EventArgs e)
		{
			BindMaterial();

			var currentPageIndex = this.PageIndex;
			var totalPages = TotalPages;

			// set pager index links
			List<PagerIndex> indexs = new List<PagerIndex>();

			if(totalPages <= 25)
			{
				for(int i = 1; i <= totalPages; i++)
				{
					indexs.Add(new PagerIndex(i.ToString()));
				}
			}
			else
			{
				for(var i = 13; i > 0; i--)
				{
					if(indexs.Count >= 27)
					{
						break;
					}

					var index = currentPageIndex - i;

					if(index > 0)
					{
						indexs.Add(new PagerIndex(index.ToString()));
					}
				}

				for(var i = 0; i <= 13; i++)
				{
					if(indexs.Count > 27)
					{
						break;
					}

					var index = currentPageIndex + i;

					if(index <= totalPages && index > 0)
					{
						indexs.Add(new PagerIndex(index.ToString()));
					}
				}
			}

			this.RptrPageIndex.DataSource = indexs;
			this.RptrPageIndex.DataBind();

			this.LabelTotalPages.Text = totalPages.ToString();
			this.LabelTotalRecords.Text = TotalRecords.ToString();

			// disenabel the current pagerindex link
			if(RptrPageIndex.Items.Count > 0)
			{
				for(int i = 0; i < RptrPageIndex.Items.Count; i++)
				{
					LinkButton thePagerIndexLink = RptrPageIndex.Items[i].FindControl("LBPageIndex") as LinkButton;

					if(thePagerIndexLink.Text.Trim().Equals((currentPageIndex + 1).ToString()))
					{
						thePagerIndexLink.Enabled = false;
					}
				}
			}

			lbtnFirstPage.Enabled = (currentPageIndex > 0);

			lbtnLastPage.Enabled = totalPages > 1 && (currentPageIndex != totalPages - 1);

			btnDelete.Visible = false;
			gvMaterial.Columns[0].Visible = false;

			var user = SiteContext.Current.CurrentUser;

			if(user != null)
			{
				if(user.Role != null)
				{
					btnDelete.Visible = user.Role.RoleName.ToLower().Equals("storeadmin") || user.Role.RoleName.ToLower().Equals("storemanager") || user.Role.RoleName.ToLower().Equals("admin");
					gvMaterial.Columns[0].Visible = user.Role.RoleName.ToLower().Equals("storeadmin") || user.Role.RoleName.ToLower().Equals("storemanager") || user.Role.RoleName.ToLower().Equals("admin");
					gvMaterial.Columns[gvMaterial.Columns.Count - 1].Visible = user.Role.RoleName.ToLower().Equals("storeadmin") || user.Role.RoleName.ToLower().Equals("storemanager") || user.Role.RoleName.ToLower().Equals("admin");
				}
			}
		}

		protected void btnDelete_Click(object sender, EventArgs e)
		{
			List<int> ids = new List<int>();
			List<string> docs = new List<string>();

			if(_MaterialProvider == null)
			{
				_MaterialProvider = new MaterialProvider();
			}

			foreach(GridViewRow row in gvMaterial.Rows)
			{
				var chbMaterial = row.FindControl("chbMaterial") as CheckBox;

				if(chbMaterial.Checked)
				{
					var hfMaterialID = row.FindControl("hfMaterialID") as HiddenField;

					var id = 0;

					if(int.TryParse(hfMaterialID.Value, out id))
					{
						ids.Add(id);

					}

					if(id > 0)
					{
						var theMaterial = _MaterialProvider.GetMaterial(id);
						if(theMaterial != null && !string.IsNullOrEmpty(theMaterial.MaterialPath))
						{
							docs.Add(theMaterial.MaterialPath);
						}
					}
				}
			}

			if(ids.Count > 0)
			{
				if(_MaterialProvider.DeleteMaterial(ids))
				{
					//BindMaterial();
				}
			}

			if(docs.Count > 0)
			{
				foreach(var p in docs)
				{
					if(File.Exists(p))
					{
						File.Delete(p);
					}
				}
			}
		}

		protected void gvMaterial_RowCommand(object sender, GridViewCommandEventArgs e)
		{
			if(e.CommandName.Equals("download"))
			{
				var materialID = int.Parse(e.CommandArgument.ToString());

				if(_MaterialProvider == null)
				{
					_MaterialProvider = new MaterialProvider();
				}

				var theMaterial = _MaterialProvider.GetMaterial(materialID);

				if(theMaterial != null)
				{
					if(DownloadMaterial(theMaterial))
					{
						var user = SiteContext.Current.CurrentUser;

						var userProvider = new UserProvider();
						user.Credits -= theMaterial.DownloadRequiedScore.GetValueOrDefault(0);

						if(userProvider.UpdateUser(user, false))
						{
							if(_MaterialProvider == null)
							{
								_MaterialProvider = new MaterialProvider();
							}

							theMaterial.DowloadCount = theMaterial.DowloadCount.GetValueOrDefault(0) + 1;

							_MaterialProvider.UpdateMaterial(theMaterial);
						}
					}

					Response.End();
				}
			}

			if(e.CommandName.Equals("update"))
			{
				var materialID = int.Parse(e.CommandArgument.ToString());

				Response.Redirect("~/MaterialEdit.aspx?materialid=" + materialID.ToString());
			}
		}

		protected void gvMaterial_RowDataBound(object sender, GridViewRowEventArgs e)
		{
			if(e.Row.DataItem != null)
			{
				var dataItem = e.Row.DataItem as Material;

				var hlMaterial = e.Row.FindControl("hlMaterial") as HyperLink;
				var lbtnDownloadMaterial = e.Row.FindControl("lbtnDownloadMaterial") as LinkButton;
				var lbtnEditMaterial = e.Row.FindControl("lbtnEditMaterial") as LinkButton;

				var hfMaterialID = e.Row.FindControl("hfMaterialID") as HiddenField;

				hfMaterialID.Value = dataItem.MaterialID.ToString();

				if(dataItem.MaterialName.Length > 21)
				{
					hlMaterial.Text = dataItem.MaterialName.Substring(0, 21) + "...";
				}
				else
				{
					hlMaterial.Text = dataItem.MaterialName;
				}
				hlMaterial.ToolTip = dataItem.MaterialName;

				if(!string.IsNullOrEmpty(dataItem.MaterialPath))
				{
					var p = dataItem.MaterialPath.Split('\\');
					var key = string.Empty;
					if(p != null && p.Length > 0)
					{
						key = p[p.Length - 1];
					}

					if(string.IsNullOrEmpty(key))
					{
						hlMaterial.Enabled = false;
						hlMaterial.ToolTip = "文档不可用";
					}
					else
					{
						hlMaterial.NavigateUrl = "~/DocumentViewer.aspx?key=" + key;
						hlMaterial.Target = "_blank";
					}
				}

				lbtnDownloadMaterial.CommandArgument = dataItem.MaterialID.ToString();
				lbtnEditMaterial.CommandArgument = dataItem.MaterialID.ToString();
			}
		}

		protected void ddlMaterialCategory_SelectedIndexChanged(object sender, EventArgs e)
		{
			//BindMaterial();
		}

		private void BindMaterial()
		{
			var data = this.DataSourse;

			gvMaterial.DataSource = data;
			gvMaterial.DataBind();
		}

		private void BindMaterialCategory()
		{
			if(_MaterialProvider == null)
			{
				_MaterialProvider = new MaterialProvider();
			}

			ddlMaterialCategory.Items.Clear();

			ddlMaterialCategory.DataSource = _MaterialProvider.GetAllMaterialCategory();
			ddlMaterialCategory.DataBind();

			ddlMaterialCategory.Items.Insert(0, new ListItem("全部", "0"));
		}

		private bool DownloadMaterial(Material theMaterial)
		{
			if(theMaterial != null && !string.IsNullOrEmpty(theMaterial.MaterialPath))
			{
				if(IsEligibleUser(theMaterial))
				{
					var mtrPathPart = theMaterial.MaterialPath.Split('\\');
					var fileName = mtrPathPart[mtrPathPart.Length - 1];
					var newFileName = string.Format("{0}.{1}", theMaterial.MaterialName, fileName.Split('.')[1]);
					var filePath = Server.MapPath("~/Document");
					FileInfo fileInfo = new FileInfo(theMaterial.MaterialPath);
					FileStream fs = new FileStream(theMaterial.MaterialPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite);
					BinaryReader br = new BinaryReader(fs);

					if(fileInfo.Exists)
					{
						try
						{
							long startBytes = 0;
							string lastUpdateTiemStamp = File.GetLastWriteTimeUtc(filePath).ToString("r");
							string _EncodedData = HttpUtility.UrlEncode(newFileName, Encoding.UTF8) + lastUpdateTiemStamp;

							Response.Clear();
							Response.Buffer = false;
							Response.AddHeader("Accept-Ranges", "bytes");
							Response.AppendHeader("ETag", "\"" + _EncodedData + "\"");
							Response.AppendHeader("Last-Modified", lastUpdateTiemStamp);
							Response.ContentType = "application/octet-stream";
							Response.AddHeader("Content-Disposition", "attachment;filename=" + HttpUtility.UrlEncode(newFileName, System.Text.Encoding.UTF8));
							Response.AddHeader("Content-Length", (fileInfo.Length - startBytes).ToString());
							Response.AddHeader("Connection", "Keep-Alive");
							Response.ContentEncoding = Encoding.UTF8;

							//Send data
							br.BaseStream.Seek(startBytes, SeekOrigin.Begin);

							//Dividing the data in 1024 bytes package
							int maxCount = (int)Math.Ceiling((fileInfo.Length - startBytes + 0.0) / 1024);

							//Download in block of 1024 bytes
							int i;
							for(i = 0; i < maxCount && Response.IsClientConnected; i++)
							{
								Response.BinaryWrite(br.ReadBytes(1024));
								Response.Flush();
							}
							//if blocks transfered not equals total number of blocks
							if(i < maxCount)
							{
								return false;
							}

							return true;
						}
						catch
						{
							return false;
						}
						finally
						{
							br.Close();
							fs.Close();
						}
					}
					else
					{
						return false;
					}
				}
				else
				{
					return false;
				}
			}
			else
			{
				return false;
			}
		}

		private bool IsEligibleUser(Material theMaterial)
		{
			var result = false;

			var user = SiteContext.Current.CurrentUser;

			if(user != null)
			{
				result = user.Credits >= theMaterial.DownloadRequiedScore.GetValueOrDefault(0);
			}

			return result;
		}
	}
}